package org.frxm.utilslibrary;

import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.util.HashMap;

import javax.crypto.Cipher;

/**
 * 作者 frxm
 * 时间 2017/1/4
 * 版本 1
 * RSA:使用公私钥进行加解密
 * 非对称加密
 * 使用流程：
 * S创建密钥对象，通过私钥加密数据并生成签名
 * C接收公钥和对应的签名还有加密数据
 * 通过签名验证公钥是否可用，可用就使用公钥进行解密
 * 回复数据使用公钥加密
 * S接收C的加密数据使用私钥进行解密
 *
 */

public class RSA {
    private final static String key1="RSAPublicKEY";
    private final static String key2="RSAPrivateKEY";
    private static HashMap<String,Key> map;
    static {
        map=new HashMap<>();
    }
    /*创建密钥对象*/
    public static void initKey()
    {
        try {
            KeyPairGenerator kpg=KeyPairGenerator.getInstance("RSA");
            kpg.initialize(1024);
            //获取随机生成的密钥对
            KeyPair kp=kpg.generateKeyPair();
            map.put(key1,kp.getPublic());
            map.put(key2,kp.getPrivate());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /*获取公钥*/
    public static Key getPublicKey()
    {
        return  map.get(key1);
    }
    /*获取私钥*/
    public static Key getPrivateKey()
    {
        return map.get(key2);
    }
    /*加密-私钥*/
    public static byte[] encryptPrivateRSA(Key privateKey,byte[] data){
//        PKCS8EncodedKeySpec peks=new PKCS8EncodedKeySpec(privateKey.getEncoded());
        try {
            Cipher cipher=Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE,privateKey);
            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /*加密-公钥*/
    public static byte[] encryptPublicRSA(Key publicKey,byte[] data){
//        X509EncodedKeySpec xeky=new X509EncodedKeySpec(publicKey.getEncoded());
        try {
            Cipher cipher=Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE,publicKey);
            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /*解密-私钥*/
    public static byte[] decodePrivateRSA(Key privateKey,byte[] data)
    {
//        PKCS8EncodedKeySpec peks=new PKCS8EncodedKeySpec(privateKey.getEncoded());
        try {
            Cipher cipher=Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE,privateKey);
            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /*解密-公钥*/
    public static byte[] decodePublicRSA(Key publicKey,byte[] data)
    {
//        X509EncodedKeySpec xeky=new X509EncodedKeySpec(publicKey.getEncoded());
        try {
            Cipher cipher=Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE,publicKey);
            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
/*生成签名文件
* 参数说明：
* 1、私钥
* 2、加密之后数据*/
    public static byte[] sign(Key privayeKey,byte[] data){
        try {
            //创建签名对象，指明签名的格式为md5为RSA提供
            Signature signature=Signature.getInstance("MD5withRSA");
            signature.initSign((PrivateKey) privayeKey);
            signature.update(data);
            return signature.sign();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /*验证签名是否合法
    * 参数说明：
    * 1、公钥
    * 2、签名
    * 3、加密的内容*/
    public static boolean verifySign(Key publicKey,byte[] sign,byte[]data)
    {
        try {
            Signature signature=Signature.getInstance("MD5withRSA");
            signature.initVerify((PublicKey) publicKey);
            signature.update(data);
            return signature.verify(sign);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}
